package com.ruoyi.web.controller.df;

import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ProcessStopException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.SseEmitterUtils;
import com.ruoyi.common.utils.biz.ResultSaveModule;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.df.domain.DensityMergeParam;
import com.ruoyi.df.service.AtmosphericDensityGridService;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.web.server.service.ResultSaveService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * </p>
 *
 * @author liuhl
 * @since 2024-06-25
 */

@RestController
@RequestMapping("/df/densityGrid")
@Api(value = "AtmosphericDensityGridController", tags = "数据融合-大气密度数据格网化处理")
@Slf4j
public class AtmosphericDensityGridController extends BaseController {

    @Resource
    private AtmosphericDensityGridService atmosphericDensityGridService;

    @Autowired
    private ISysDictTypeService dictTypeService;

    @Autowired
    private ResultSaveService resultSaveService;

    //@PreAuthorize("@ss.hasPermi('df:densityGrid:getMergeData')")
    @ApiOperation(value = "获取经纬度格网化处理数据", notes = "获取经纬度格网化处理数据")
    @PostMapping("/getMergeData")
    public AjaxResult getMergeData(@RequestBody Map<String, Object> map
    ) throws ProcessStopException {
        String sseId = map.get("sseId")+ SecurityUtils.getLoginUser().getUsername();
        try {
            return  atmosphericDensityGridService.getMergeData(map);
        }finally {
            SseEmitterUtils.sendMessage(sseId, "100");
            SseEmitterUtils.remove(sseId);
        }
    }
    @ApiOperation(value = "获取经纬度格网化处理数据", notes = "获取经纬度格网化处理数据")
    @PostMapping("/new/getMergeData")
    public AjaxResult newMergeData(@RequestBody DensityMergeParam param,@RequestParam(value = "rdtmp",required = false,defaultValue = "0") Long rdtmp) throws Exception {
        String sseId = param.getSseId()+ SecurityUtils.getLoginUser().getUsername();
        try {
            AjaxResult ajaxResult = atmosphericDensityGridService.getNewMergeData(param);
            Object data = ajaxResult.get(AjaxResult.DATA_TAG);
            if(ajaxResult.isError()){
               /* if(Objects.nonNull(data) && data instanceof String){
                    ajaxResult.setMsg(ajaxResult.get(AjaxResult.DATA_TAG).toString());
                }*/
                return ajaxResult;
            }

            saveNewMergeData(sseId,rdtmp,param,(Map)data);
            return ajaxResult;
        }finally {
            SseEmitterUtils.sendMessage(sseId, "100");
            SseEmitterUtils.remove(sseId);
        }
    }

    //@PreAuthorize("@ss.hasPermi('df:densityGrid:show')")
    @ApiOperation(value = "进行结果展示", notes = "进行结果展示")
    @GetMapping("/show")
    public AjaxResult show(@ApiParam(value = "路径", name = "path") @RequestParam(value = "path",required = false) String path) {
        return atmosphericDensityGridService.show(path);
    }
    //@PreAuthorize("@ss.hasPermi('df:densityGrid:subscribe')")
    @ApiOperation(value = "建立连接", notes = "建立连接")
    @GetMapping(path = "subscribe", produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
    public SseEmitter push(String id, String flag) {
        return atmosphericDensityGridService.push(id,flag);
    }

    //@PreAuthorize("@ss.hasPermi('df:densityGrid:save')")
    @ApiOperation(value = "结果入库", notes = "结果入库")
    @PostMapping("/save")
    public AjaxResult save(@RequestBody List<Map<String, Object>> list) {
        return atmosphericDensityGridService.save(list);
    }

    //@PreAuthorize("@ss.hasPermi('df:densityGrid:list')")
    @ApiOperation(value = "获取资料列表", notes = "获取资料列表")
    @GetMapping("/list")
    public TableDataInfo list(@ApiParam(value = "卫星名称", name = "staName") @RequestParam(value = "staName",required = false) String staName,
                              @ApiParam(value = "开始时间（yyyy-MM-dd）", name = "startTime") @RequestParam(value = "startTime",required = false) String startTime,
                              @ApiParam(value = "结束时间（yyyy-MM-dd）", name = "endTime") @RequestParam(value = "endTime",required = false) String endTime,
                              @ApiParam(value = "表名", name = "tableName") @RequestParam("tableName") String tableName) {
        startPage();
        List<Map<String, Object>> list = atmosphericDensityGridService.selectList(staName, startTime, endTime, tableName);
        return getDataTable(list);
    }

//    //@PreAuthorize("@ss.hasPermi('df:densityGrid:getTimeNormalization')")
//    @ApiOperation(value = "时间归一化处理", notes = "时间归一化处理")
//    @PostMapping("/getTimeNormalization")
//    public AjaxResult getTimeNormalization(@RequestBody Map<String, Object> map) {
//        return atmosphericDensityGridService.getTimeNormalization(map);
//    }

    @ApiOperation(value = "地方时格网化-计算", notes = "计算")
    @GetMapping("/calc")
    public R<Map> list(@ApiParam(value = "高度", name = "hight") @RequestParam(value = "hight",required = false) Integer hight,
                          @ApiParam(value = "sseId", name = "sseId") @RequestParam(value = "sseId",required = false) String sseId,
                          @ApiParam(value = "时间", name = "time") @RequestParam(value = "time",required = false) Date time
                              ) {
        String[] res = atmosphericDensityGridService.calculateGrid(time, hight,sseId);
        //提取图片路径
        Map<String, Object> resMap = new HashMap<>();
        String txtPath = res[1];
        String pngPath = res[2];
        resMap.put("result", pngPath);
        resMap.put("resultData", JSONUtil.toJsonStr(Stream.of(txtPath,pngPath).collect(Collectors.toList())));
        resMap.put("module", ResultSaveModule.DATA_FUSION);
        resMap.put("submodule", ResultSaveModule.DATA_FUSION_TIME_GRID);
        return R.ok(resMap);
    }

    @ApiOperation(value = "地方时格网化-结果保存", notes = "结果保存")
    @GetMapping("/calc/save")
    public void calcSave(HttpServletResponse response,
                      @ApiParam(value = "高度", name = "hight") @RequestParam(value = "hight",required = false) Integer hight,
                      @ApiParam(value = "时间", name = "time") @RequestParam(value = "time",required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date time
    ) {
        File file = atmosphericDensityGridService.calculateGridSave(time, hight);
        try {
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, file.getName());
            FileUtils.writeBytes(file.getAbsolutePath(), response.getOutputStream());
        }catch (Exception e) {
            log.error("下载失败",e);
        }
    }

    @ApiOperation(value = "卫星列表", notes = "结果保存")
    @GetMapping("/calc/sate")
    public AjaxResult sate() {
        List<SysDictData> data = dictTypeService.selectDictDataByType("air_den_satellite");
        List<SysDictData> collect = data.stream().filter(one -> !"FY3C".equals(one.getDictValue())).collect(Collectors.toList());
        return AjaxResult.success(collect);
    }


    private void saveNewMergeData(String sseId, Long rdtmp,DensityMergeParam param,Map data){
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(JSONObject.parseObject(JSONObject.toJSONString(param)));
        Map saveParam = new HashMap<>();
        saveParam.put("sseId",sseId);
        saveParam.put("param",jsonArray);
        saveParam.putAll(data);
        saveParam.remove("result");
        String resultData = MapUtil.getStr(saveParam,"resultData");
        saveParam.remove("resultData");
        log.info("getMergeData finished. start save Result. rdtmp:{}, param:{}", rdtmp,saveParam);
        saveParam.put("resultData",resultData);
        AjaxResult saveResult = resultSaveService.resultSave(saveParam);
        if(saveResult.isError()){
            log.error("getMergeData saveResult error. rdtmp:{},param:{},result:{}",rdtmp,JSONUtil.toJsonStr(saveParam),JSONUtil.toJsonStr(saveResult));
        }
    }
}
